package trocabi.view;

import trocabi.DAO.DAOArticle;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import trocabi.TROCABI;
import trocabi.model.Article;
import trocabi.model.Depositaire;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ButtonModel;
import javax.swing.JComboBox;
import trocabi.Socle.JDateTextField;
import trocabi.Socle.JNumberTextField;
import trocabi.Socle.JPriceTextField;
import trocabi.Socle.TechnicalException;
import static trocabi.TROCABI.ERREUR;
import static trocabi.TROCABI.fenetreExterne;
import static trocabi.model.Article.codeToMarge;
import trocabi.service.ArticleServices;
import trocabi.service.DepositaireServices;

public class GuiSaisieArticle extends JFrame implements DocumentListener {
    private static final Logger    logger = Logger.getLogger("trocabi.view.GuiSaisieArticle"); 
    public enum                    Mode  { CREATE, UPDATE, VIEW };
    private Mode                   currentMode;
    private DAOArticle             daoArticle = DAOArticle.getInstance();
    private DepositaireServices    depositaireServices=new DepositaireServices();
    private ArticleServices        articleServices=new ArticleServices();
    private Depositaire            depositaire;
    private Article                article=null;
    private JTextField             fieldIdDepositaire;
    private JTextField             fieldIdArticle;
    private JDateTextField         fieldDateDepot; 
    private JPriceTextField        fieldPrixAchat;
    private JTextArea              fieldDescription;
    private JTextField             fieldStatus;
    private JNumberTextField       fieldQuantite=new JNumberTextField("###");
    private JButton                btAnnuler = new JButton("Annuler");
    private JButton                btDeposer = new JButton("Déposer un autre article");
    private JButton                btTerminer = new JButton("Terminer");
    private ButtonGroup            bgAspect = new ButtonGroup();;
    private JRadioButton           aspectButton[]=new JRadioButton[Article.aspect.length];
    private ButtonGroup            bgGenre = new ButtonGroup();
    private JRadioButton           genreButton[]=new JRadioButton[Article.genre.length];
    private ButtonGroup            bgType = new ButtonGroup();
    private JRadioButton           typeButton[]=new JRadioButton[Article.type.length];
    private JComboBox              btColors = new JComboBox(Article.colors);
    private GuiDeposerArticles     fDepot;
    private JPanel                 pContentPanel;
    private JPanel                 pCenter;
    private JPanel                 pInfos;
    private JPanel                 pBoutons;
    private JScrollPane            spDescription;
    private java.util.Date         derniereDateSaisie=null; // TODO:!
    
    public GuiSaisieArticle() {
        initComponents();
    }
    
    public void setDepotArticle(GuiDeposerArticles _fDepot) { fDepot=_fDepot; }
    

    private void initComponents() {
        this.setTitle("Dépôt d'un article");
        this.setSize(550, 650);
        this.setLocationRelativeTo(null);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        // Content panel de type BorderPanel --> nord = titre / centre = contenu / sud = licence, droits, auteurs ...
        pContentPanel = new JPanel(new BorderLayout());
        pContentPanel.setBackground(Color.white);
        this.setContentPane(pContentPanel);
        /*
         * Que du gridBagLayout
         * Panel de 3 lignes --> 3 et 2 contiennent un panel (GridBagLayout)
         */
        pCenter = new JPanel(new GridBagLayout());
        GridBagConstraints tmp = new GridBagConstraints();

        // Label Nom, Prénom, ID
        fieldIdDepositaire=new JTextField();
        fieldIdDepositaire.setEditable(false);
        fieldIdDepositaire.setPreferredSize(new Dimension(150, 20));
        tmp.gridx = 0;
        tmp.gridy = 0;
        tmp.insets = new Insets(10, 10, 0, 10);
        tmp.fill = GridBagConstraints.HORIZONTAL;
        pCenter.add(fieldIdDepositaire, tmp);

        // Sous-panel "Informations"
        pInfos = new JPanel(new GridBagLayout());
        tmp.fill = GridBagConstraints.NONE;
        tmp.anchor = GridBagConstraints.LINE_END;
        // Labels
        pInfos.add(new JLabel("Référence Article"), tmp);
        tmp.gridy = 1;
        pInfos.add(new JLabel("Date de dépôt"), tmp);
        tmp.gridy = 2;
        pInfos.add(new JLabel("Type"), tmp);
        tmp.gridy = 6;
        pInfos.add(new JLabel("Aspect"), tmp);
        tmp.gridy = 9;
        pInfos.add(new JLabel("Description"), tmp);
        tmp.gridy = 13;
        pInfos.add(new JLabel("Prix achat"), tmp);
        tmp.gridx = 2;
        tmp.gridy = 0;
        pInfos.add(new JLabel("Situation"), tmp);
        tmp.gridy = 2;
        pInfos.add(new JLabel("Pour"), tmp);
        tmp.gridy = 5;
        pInfos.add(new JLabel("Couleur"), tmp);
        tmp.gridy = 13;
        pInfos.add(new JLabel("Quantité"), tmp);
        // TextFields
        fieldIdArticle = new JTextField();
        fieldIdArticle.setEditable(false);
        fieldIdArticle.setPreferredSize(new Dimension(100, 20));
        tmp.anchor = GridBagConstraints.LINE_START;
        tmp.gridx = 1;
        tmp.gridy = 0;
        pInfos.add(fieldIdArticle, tmp);
        try {
            if (derniereDateSaisie==null) fieldDateDepot = new JDateTextField("dd/MM/yy", new java.util.Date()); // date par defaut
            else fieldDateDepot = new JDateTextField("dd/MM/yy"); // date par defaut
            fieldDateDepot.setColumns(10);
            fieldDateDepot.getDocument().addDocumentListener(this);
            fieldDateDepot.setPreferredSize(new Dimension(100, 20));
           
         
            tmp.gridy = 1;
            pInfos.add(fieldDateDepot, tmp); 
        } catch (ParseException e) { // TODO: move it
            logger.severe(String.format("%s %s",e.getLocalizedMessage(),e.getMessage()));
        }
        JPanel pPrix = new JPanel(new GridBagLayout());
        fieldPrixAchat = new JPriceTextField(); 
        fieldPrixAchat.getDocument().addDocumentListener(this);
        fieldPrixAchat.setPreferredSize(new Dimension(70, 20));
        fieldPrixAchat.setPrice(0.0);
        tmp.gridx = 0;
        tmp.gridy = 0;
        pPrix.add(fieldPrixAchat);
        tmp.gridx = 1;
        tmp.gridy = 13;
        pInfos.add(pPrix, tmp);
        fieldStatus = new JTextField();
        fieldStatus.setPreferredSize(new Dimension(100, 20));
        fieldStatus.setEditable(false);
        tmp.gridx = 3;
        tmp.gridy = 0;
        pInfos.add(fieldStatus, tmp);
        fieldQuantite.setPreferredSize(new Dimension(100, 20));
        tmp.gridy = 13;
        pInfos.add(fieldQuantite, tmp);
        // Radio-Boutons
     
        // set Type buttons
        int offset=2; tmp.gridx = 1;
        for (int i = 0; i < Article.type.length; i++) {
            typeButton[i] = new JRadioButton(Article.type[i][0]);
            typeButton[i].setActionCommand(Article.type[i][1]);
            typeButton[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    checkInformations();
                }
            });
            bgType.add(typeButton[i]);
            tmp.gridy = i + offset;
            pInfos.add(typeButton[i], tmp);
        }
        // set Aspect buttons
        
        offset=6;
        for (int i=0; i<Article.aspect.length; i++) {
            aspectButton[i]=new JRadioButton((String) Article.aspect[i][0]);
            aspectButton[i].setActionCommand((String) Article.aspect[i][1]);
            aspectButton[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    checkInformations();
                }
            });
            bgAspect.add(aspectButton[i]);
            tmp.gridy = i+offset;
            pInfos.add(aspectButton[i], tmp);
        }
         // set Aspect buttons
        offset=2;  tmp.gridx = 3;
        for (int i=0; i<Article.aspect.length; i++) {
            genreButton[i]=new JRadioButton(Article.genre[i][0]);
            genreButton[i].setActionCommand(Article.genre[i][1]);
            genreButton[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    checkInformations();
                }
            });
            bgGenre.add(genreButton[i]);
            tmp.gridy = i+offset;
            pInfos.add(genreButton[i], tmp);
        }
        // set Colors choice
        btColors.setSelectedIndex(1);
        btColors.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    checkInformations();
                }
            });
        tmp.gridy = 5;
        pInfos.add(btColors, tmp);
        // Zone de texte
        spDescription = new JScrollPane();
        fieldDescription = new JTextArea();
        fieldDescription.setLineWrap(true);
        fieldDescription.getDocument().addDocumentListener(this);
        spDescription.add(fieldDescription);
        spDescription.setViewportView(fieldDescription);
        tmp.gridx = 1;
        tmp.gridy = 9;
        tmp.weightx = 1;
        tmp.weighty = 1;
        tmp.gridwidth = 2;
        tmp.gridheight = 4;
        tmp.fill = GridBagConstraints.BOTH;
        pInfos.add(spDescription, tmp);
        tmp.gridx = 0;
        tmp.gridy = 1;
        tmp.gridwidth = 1;
        tmp.gridheight = 1;
        tmp.fill = GridBagConstraints.BOTH;
        pCenter.add(pInfos, tmp);

        // Sous-panel "Boutons"
        pBoutons = new JPanel(new GridBagLayout());
        
        btAnnuler.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                   setVisible(false);
            }
        });
        tmp.gridx = 0;
        tmp.gridy = 0;
        tmp.weighty = 0;
        tmp.insets = new Insets(10, 10, 10, 10);
        tmp.fill = GridBagConstraints.NONE;
        tmp.anchor = GridBagConstraints.LINE_START;
        pBoutons.add(btAnnuler, tmp);
       
        btTerminer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                   if (currentMode==Mode.CREATE) deposerArticle();
                   else majArticle();
                   setVisible(false);
                   clear();
            }
        });
        tmp.gridx = 2;
        tmp.anchor = GridBagConstraints.LINE_END;
        pBoutons.add(btTerminer, tmp);
        btDeposer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                   deposerArticle();
                   clear();
            }
        });
        tmp.gridx = 1;
        tmp.weightx = 1;
        tmp.anchor = GridBagConstraints.LINE_END;
        pBoutons.add(btDeposer, tmp);
        tmp.gridx = 0;
        tmp.gridy = 2;
        tmp.fill = GridBagConstraints.HORIZONTAL;
        pCenter.add(pBoutons, tmp);
        pContentPanel.add(pCenter, BorderLayout.CENTER);
    }

    public void clear() {
        article = null;
        this.setLocationRelativeTo(null);
        fieldIdArticle.setText("");
        if (derniereDateSaisie==null) fieldDateDepot.setDate(new java.util.Date());
        else fieldDateDepot.setDate(derniereDateSaisie);
        fieldDateDepot.setText(""); // TODO:check it
        fieldPrixAchat.setPrice(0.0);
        fieldStatus.setText("");
        fieldQuantite.setText("1");
        fieldQuantite.setEnabled(false);
        fieldDescription.setText("");
        bgType.clearSelection();
        bgAspect.clearSelection();
        bgGenre.clearSelection();     
        // bgCouleur.clearSelection();
        btTerminer.setEnabled(false);
        btDeposer.setEnabled(false);
    }

    public void setMode(Mode mode) { 
        currentMode=mode;
        switch(mode) {
            case CREATE:
                setTitle("Dépôt d'un nouvel article");
                clear();
                fieldQuantite.setEditable(false);
                btAnnuler.setVisible(true);
                btDeposer.setVisible(true);
                btTerminer.setVisible(true);
                break;
            case UPDATE:
                setTitle("Mise à jour d'un article en dépôt");
                fieldQuantite.setEditable(false);
                btAnnuler.setVisible(true);
                btDeposer.setVisible(false);
                btTerminer.setVisible(true);
                break;
            case VIEW:
                setTitle("Visualisation d'un article en dépôt");
                fieldQuantite.setEditable(false);
                btAnnuler.setVisible(false);
                btDeposer.setVisible(false);
                btTerminer.setVisible(true);
                break;
        }
    }
    
    private void setAspect(String code) {
        for (int i = 0; i < aspectButton.length; i++) {
            if (aspectButton[i].getActionCommand().compareTo(code) == 0) {
                aspectButton[i].setSelected(true);
                return;
            }
        }
        logger.severe(String.format("Code Aspect Invalide (%s)",code));
    }
    
    private void setGenre(String code) {
        for (int i = 0; i < genreButton.length; i++) {
            if (genreButton[i].getActionCommand().compareTo(code) == 0) {
                genreButton[i].setSelected(true);
                return;
            }
        }
        logger.severe(String.format("Code Genre Invalide (%s)",code));
    }
    private void setType(String code) {
        for (int i = 0; i < typeButton.length; i++) {
            if (typeButton[i].getActionCommand().compareTo(code) == 0) {
                typeButton[i].setSelected(true);
                return;
            }
        }
        logger.severe(String.format("Code Type Invalide (%s)",code));
    }
    private void setColor(String code) {
        for (int i = 0; i < Article.colors.length; i++) {
            if (Article.colors[i].compareTo(code)==0) {
                btColors.setSelectedIndex(i);
                return;
            }
        }
        logger.severe(String.format("Code Couleur Invalide (%s)",code));
    }
    public void setDepositaire(Depositaire depositaire) {
        this.depositaire = depositaire;
        fieldIdDepositaire.setText(depositaireServices.idToString(depositaire));
    }

    public void setArticle(Article atArticle_tmp) {
        article = atArticle_tmp;
        fieldStatus.setText(Article.etatToString(article.getSituation()));
        fieldIdArticle.setText(articleServices.idToString(article));
        fieldDateDepot.setDate(article.getDateDepot());
        fieldPrixAchat.setPrice(article.getPrixAchat());
        fieldQuantite.setText("1");
        fieldDescription.setText(article.getDescription());
        setType(article.getCodeType());
        setGenre(article.getCodeGenre());
        setColor(article.getCouleur());
        setAspect(article.getCodeAspect());
        btTerminer.setEnabled(true);
        btDeposer.setEnabled(true);
    }

   
    
    public void checkTextArea() {
        if (fieldDescription.getText().length() >= 255) {
            TROCABI.fenetreExterne(TROCABI.STOP, "La taille limite du texte de description de l'article est de 255 caractères. Tout le texte en trop sera tronqué.");
        }
    }

    public void checkInformations() {
        boolean test = fieldDateDepot.getDate()!=null
                && fieldPrixAchat.getPrice() != 0.0
                && bgType.getSelection() != null
                && bgAspect.getSelection() != null
                && bgGenre.getSelection() != null
                && btColors.getSelectedIndex() >= 0
                && fieldQuantite.getNumber()>0;
        
        ButtonModel aspect = bgAspect.getSelection();
        if (aspect!=null && currentMode==Mode.CREATE && aspect.getActionCommand().equals("N")) {
            fieldQuantite.setEnabled(true);
        }
        else {
            fieldQuantite.setEnabled(false);
        }
        btTerminer.setEnabled(test);
        btDeposer.setEnabled(test);
    }
    
    private void deposerArticle() {
        int compteur=0;
        ButtonModel aspect = bgAspect.getSelection();
        ButtonModel genre = bgGenre.getSelection();
        ButtonModel type = bgType.getSelection();
        String couleur = Article.codeToColor(btColors.getSelectedIndex());
        long quantite = (Long) fieldQuantite.getNumber();

        try {
            for (int i = 0; i < quantite; i++) {
                Article newArticle = new Article(depositaire.getId(),
                        fieldDateDepot.getDate(),
                        fieldDescription.getText(),
                        aspect.getActionCommand(), 
                        genre.getActionCommand(),
                        type.getActionCommand(),
                        couleur,
                        fieldPrixAchat.getPrice());
                
                articleServices.create(newArticle);
                setArticle(newArticle);
                fDepot.addArticles(article); // maj de la liste des articles
                compteur++;
            }
        } catch (TechnicalException e) {
            logger.severe(String.format("%s %s",e.getLocalizedMessage(),e.getMessage()));
            fenetreExterne(ERREUR, "Erreur inattendue lors de la création de l'article.\nNombre d'exemplaires de l'article déjà créés : " + compteur);
        }
    }
    private void majArticle() {
        ButtonModel aspect = bgAspect.getSelection();
        ButtonModel genre = bgGenre.getSelection();
        ButtonModel type = bgType.getSelection();
        String couleur = Article.codeToColor(btColors.getSelectedIndex());
        
        try {
            Article newArticle = new Article(article.getId(),depositaire.getId(), fieldDescription.getText(),
                        aspect.getActionCommand(), genre.getActionCommand(),type.getActionCommand(),
                        couleur, article.getSituation(), article.getCommentaire(), article.getCodeCaisse(),
                        fieldPrixAchat.getPrice(), codeToMarge(aspect.getActionCommand()),
                        fieldDateDepot.getDate(),
                        article.getDatePaiementDepositaire(),
                        article.getDateAchat(),new Date());              
                articleServices.update(newArticle);
                setArticle(newArticle);
        } catch (TechnicalException e) {
            logger.severe(String.format("%s %s",e.getLocalizedMessage(),e.getMessage()));
            fenetreExterne(ERREUR, "Erreur inattendue lors de la mise à jour de l'article");
        }
    }
    @Override
    public void insertUpdate(DocumentEvent de) {
        checkInformations();
    }

    @Override
    public void removeUpdate(DocumentEvent de) {
        checkInformations();
    }

    @Override
    public void changedUpdate(DocumentEvent de) {
        checkInformations();
    }
}

